package com.yhos.platform.oopston.core.aop;

import com.yhos.platform.oopston.base.config.OopstonConfig;
import com.yhos.platform.oopston.base.constants.BaseOperatorConstant;
import com.yhos.platform.oopston.core.dto.RequestBaseDTO;
import com.yhos.platform.oopston.core.exception.BusinessException;
import com.yhos.platform.oopston.core.utils.MessageSourceUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Aspect
@Order(1)
public class BaseSecretAspect {

    private static Logger LOGGER = LoggerFactory.getLogger(BaseSecretAspect.class);

    @Autowired
    private MessageSourceUtils messageSourceUtils;

    @Autowired
    private OopstonConfig oopstonConfig;

    //具体按照各自项目中Controller目录去设定切点
    @Pointcut("execution(* com.yhos.platform.oopston.web.*.*.*(..))")
    public void controllerMethodPointcut() {

    }

    @Around("controllerMethodPointcut()")
    public Object processAspect(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        validAppSecret(method, args);
        return point.proceed();
    }

    private void validAppSecret(Method method, Object[] args) throws BusinessException {
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
            //多个参数循环
            for (int i = 0; i < parameterAnnotations.length; i++) {
                Annotation[] paramAnn = parameterAnnotations[i];
                if (paramAnn != null && paramAnn.length > 0) {
                    //参数有多个注解
                    for (int j = 0; j < paramAnn.length; j++) {
                        Annotation annotation = paramAnn[j];
                        if (RequestBody.class.isInstance(annotation) && args[i].getClass().getSuperclass() == RequestBaseDTO.class
                                || args[i].getClass().getSuperclass().getSuperclass() == RequestBaseDTO.class) {
                            RequestBaseDTO requestBaseDTO = (RequestBaseDTO) args[i];
                            if (!oopstonConfig.getInnerAppKey().equalsIgnoreCase(requestBaseDTO.getAppKey())
                                    || !oopstonConfig.getInnerAppSecret().equalsIgnoreCase(requestBaseDTO.getAppSecret())) {
                                throw new BusinessException(messageSourceUtils.getMessage(BaseOperatorConstant.APP_KEY_AND_SECRET_IS_INVALID), BaseOperatorConstant.APP_KEY_AND_SECRET_IS_INVALID);
                            }
                            break;
                        }
                    }
                }
            }
        }
    }

    public void setMessageSourceUtils(MessageSourceUtils messageSourceUtils) {
        this.messageSourceUtils = messageSourceUtils;
    }

    public void setOopstonConfig(OopstonConfig oopstonConfig) {
        this.oopstonConfig = oopstonConfig;
    }
}
